

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define BSP_ADC_CHANNEL_NUM 1

ADC_HandleTypeDef ADC1_Handler;
DMA_HandleTypeDef DMA_Handle = {0};
ADC_ChannelConfTypeDef ADC1_ChanConf;

#if defined ( __CC_ARM )
ALIGN_32BYTES (__attribute__((at(0x30000000))) uint16_t ADCxValues[3]);
#elif defined ( __GNUC__ )
uint16_t ADCxValues[BSP_ADC_CHANNEL_NUM] __attribute__((section(".ADCArraySection")));
#endif

uint16_t get_adc(uint8_t num)
{
    if(num == 0)
    {
        return ADCxValues[0];
    }
    else if(num == 1)
    {
        return ADCxValues[1];
    }
    else if(num == 2)
    {
        return ADCxValues[2];
    }
    else
    {
        return 0;
    }
}
int adc_test(int argc, char* argv[])
{
    rt_kprintf("adc0 value:%d\r\n" ,ADCxValues[0]);
    rt_kprintf("adc1 value:%d\r\n" ,ADCxValues[1]);
    rt_kprintf("adc2 value:%d\r\n" ,ADCxValues[2]);
//    rt_kprintf("adc3 value:%d\r\n" ,ADCxValues[3]);

    return 0;
}
//MSH_CMD_EXPORT(adc_test,e.g adc test)

int rt_hw_adc_init(void)
{
    DMA_Handle.Instance                     = DMA2_Stream7;                  //使用的DMA2 Stream7
    DMA_Handle.Init.Request                 = DMA_REQUEST_ADC1;              //请求类型采用DMA_REQUEST_ADC1
    DMA_Handle.Init.Direction               = DMA_PERIPH_TO_MEMORY;          //传输方向是从外设到存储器
    DMA_Handle.Init.PeriphInc               = DMA_PINC_DISABLE;              //外设地址自增禁止
    DMA_Handle.Init.MemInc                  = DMA_MINC_ENABLE;               //存储器地址自增使能
    DMA_Handle.Init.PeriphDataAlignment     = DMA_PDATAALIGN_HALFWORD;       //外设数据传输位宽选择半字，即16bit
    DMA_Handle.Init.MemDataAlignment        = DMA_MDATAALIGN_HALFWORD;       //存储器数据传输位宽选择半字，即16bit
    DMA_Handle.Init.Mode                    = DMA_CIRCULAR;                  //循环模式
    DMA_Handle.Init.Priority                = DMA_PRIORITY_LOW;              //优先级低
    DMA_Handle.Init.FIFOMode                = DMA_FIFOMODE_DISABLE;          //禁止FIFO
    DMA_Handle.Init.FIFOThreshold           = DMA_FIFO_THRESHOLD_FULL;       //禁止FIFO此位不起作用，用于设置阀值
    DMA_Handle.Init.MemBurst                = DMA_MBURST_SINGLE;             //禁止FIFO此位不起作用，用于存储器突发
    DMA_Handle.Init.PeriphBurst             = DMA_PBURST_SINGLE;             //禁止FIFO此位不起作用，用于外设突发

    HAL_DMA_Init(&DMA_Handle);

    __HAL_LINKDMA(&ADC1_Handler, DMA_Handle, DMA_Handle);

    ADC1_Handler.Instance                   =  ADC1;
    ADC1_Handler.Init.ClockPrescaler        =  ADC_CLOCK_ASYNC_DIV8;         //8分频，ADCCLK=PER_CK/6=50/8
    ADC1_Handler.Init.Resolution            =  ADC_RESOLUTION_16B;           //16位模式
    ADC1_Handler.Init.ScanConvMode          =  ADC_SCAN_ENABLE;              //非扫描模式
    ADC1_Handler.Init.EOCSelection          =  ADC_EOC_SINGLE_CONV;          //关闭EOC中断
    ADC1_Handler.Init.LowPowerAutoWait      =  DISABLE;                      //自动低功耗关闭
    ADC1_Handler.Init.ContinuousConvMode    =  ENABLE;                       //连续转换
    ADC1_Handler.Init.NbrOfConversion       =  BSP_ADC_CHANNEL_NUM;          //3个转换在规则序列中 也就是只转换规则序列1
    ADC1_Handler.Init.DiscontinuousConvMode =  DISABLE;                      //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion   =  0;                            //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv      =  ADC_SOFTWARE_START;           //软件触发
    ADC1_Handler.Init.ExternalTrigConvEdge  =  ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    ADC1_Handler.Init.Overrun               =  ADC_OVR_DATA_OVERWRITTEN;     //有新的数据的死后直接覆盖掉旧数据
    ADC1_Handler.Init.OversamplingMode      =  DISABLE;                       //过采样
    ADC1_Handler.Init.Oversampling.Ratio    =  15;                           //16倍过采样
    ADC1_Handler.Init.Oversampling.RightBitShift         = ADC_RIGHTBITSHIFT_4; //数据右移4bit
    ADC1_Handler.Init.Oversampling.TriggeredMode         = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
    ADC1_Handler.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
    ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR;//DMA循环模式接收ADC转换的数据

    HAL_ADC_Init(&ADC1_Handler);

    HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);

    /*configuration PA4 ADC1_INP18*/
    ADC1_ChanConf.Channel                   = ADC_CHANNEL_18;
    ADC1_ChanConf.Rank                      = ADC_REGULAR_RANK_1;
    ADC1_ChanConf.SamplingTime              = ADC_SAMPLETIME_810CYCLES_5;
    ADC1_ChanConf.SingleDiff                = ADC_SINGLE_ENDED;
    ADC1_ChanConf.OffsetNumber              = ADC_OFFSET_NONE;
    ADC1_ChanConf.Offset                    = 0;
    ADC1_ChanConf.OffsetRightShift          = DISABLE;
    ADC1_ChanConf.OffsetSignedSaturation    = DISABLE;
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);

    /*configuration PA5 ADC1_INP18*/
    ADC1_ChanConf.Channel                   = ADC_CHANNEL_19;
    ADC1_ChanConf.Rank                      = ADC_REGULAR_RANK_2;
    ADC1_ChanConf.SamplingTime              = ADC_SAMPLETIME_810CYCLES_5;
    ADC1_ChanConf.SingleDiff                = ADC_SINGLE_ENDED;
    ADC1_ChanConf.OffsetNumber              = ADC_OFFSET_NONE;
    ADC1_ChanConf.Offset                    = 0;
    ADC1_ChanConf.OffsetRightShift          = DISABLE;
    ADC1_ChanConf.OffsetSignedSaturation    = DISABLE;
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);

    /*configuration PA6 ADC1_INP3*/
    ADC1_ChanConf.Channel                   = ADC_CHANNEL_3;
    ADC1_ChanConf.Rank                      = ADC_REGULAR_RANK_3;
    ADC1_ChanConf.SamplingTime              = ADC_SAMPLETIME_810CYCLES_5;
    ADC1_ChanConf.SingleDiff                = ADC_SINGLE_ENDED;
    ADC1_ChanConf.OffsetNumber              = ADC_OFFSET_NONE;
    ADC1_ChanConf.Offset                    = 0;
    ADC1_ChanConf.OffsetRightShift          = DISABLE;
    ADC1_ChanConf.OffsetSignedSaturation    = DISABLE;
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);

//    /*configuration PA0_C ADC1_INP0*/
//    ADC1_ChanConf.Channel                   = ADC_CHANNEL_0;
//    ADC1_ChanConf.Rank                      = ADC_REGULAR_RANK_4;
//    ADC1_ChanConf.SamplingTime              = ADC_SAMPLETIME_810CYCLES_5;
//    ADC1_ChanConf.SingleDiff                = ADC_SINGLE_ENDED;
//    ADC1_ChanConf.OffsetNumber              = ADC_OFFSET_NONE;
//    ADC1_ChanConf.Offset                    = 0;
//    ADC1_ChanConf.OffsetRightShift          = DISABLE;
//    ADC1_ChanConf.OffsetSignedSaturation    = DISABLE;
//    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);

    HAL_ADC_Start_DMA(&ADC1_Handler, (uint32_t *)ADCxValues, BSP_ADC_CHANNEL_NUM);

    return RT_EOK;
}
//INIT_ENV_EXPORT(rt_hw_adc_init);

